package com.neusoft.hifly.push.sms.gateway.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

import com.neusoft.hifly.commons.exception.SystemErrorException;
import com.neusoft.hifly.commons.id.IdWorker;
import com.neusoft.hifly.core.log.Log;
import com.neusoft.hifly.push.sms.gateway.dao.ISMSToDoDao;
import com.neusoft.hifly.push.sms.gateway.pojo.SMSToDoObj;
import com.neusoft.hifly.push.sms.gateway.service.ISMSService;

/**
 * Title: 短信服务
 * <p>
 * Description: 短信
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
@Service("smsService")
public class SMSServiceImpl implements ISMSService {
	@Autowired(required = false)
	private IdWorker idWorker;
	@Autowired(required = false)
	private ISMSToDoDao smsToDoDao;

	/**
	 * 后备策略
	 * <p>
	 *  需要在@HystrixCommand注解中添加一个名为fallbackMethod的属性
	 * <p>
	 *  后备方法必须跟使用了@HysrixCommand原始方法在同一个类中
	 * <p>
	 *  后备方法必须是public类型
	 * <p>
	 *  后备方法参数必须和原方法一致
	 *
	 * @param sender
	 *            发送者
	 * @param receivers
	 *            接收者的手机号码
	 * @param message
	 *            发送的信息内容
	 * @param organLogicId
	 *            租户逻辑ID
	 * @return 错误信息
	 */
	public boolean fallBackSendMessage(final String sender, final List<String> receivers, final String message,
			final long organLogicId) {
		Log.error("系统熔断！");
		return false;
	}

	/**
	 * 发送短信
	 *
	 * @param sender
	 *            发送者
	 * @param receivers
	 *            接收者的手机号码
	 * @param message
	 *            发送的信息内容
	 * @param organLogicId
	 *            租户逻辑ID
	 * @return 返回 如果发送成功返回true 否则返回false
	 */
	@Override
	@HystrixCommand(fallbackMethod = "fallBackSendMessage", ignoreExceptions = SystemErrorException.class, commandProperties = {
			// 请求超时时间
			@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
			// 请求最小次数
			@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "4"),
			// 失败率阈值%
			@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
			// 熔断断开后,间隔7s,就尝试访问一次服务,查看服务是否已经恢复
			@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "7000"),
			// 时间窗口,从监听到第一次失败开始计时
			@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "15000"),
			// 在时间窗口中,收集统计信息的次数。在15s的窗口中每隔3s就收集一次,共5次。
			@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "5") })
	public boolean sendMessage(final String sender, final List<String> receivers, final String message,
			final long organLogicId) {
		if ((receivers == null) || (receivers.size() == 0) || StringUtils.isEmpty(message)) {
			return false;
		}

		SMSToDoObj obj = null;

		for (final String receiver : receivers) {
			if (StringUtils.isEmpty(receiver)) {
				continue;
			}

			obj = new SMSToDoObj();
			obj.setId(idWorker.nextId());
			obj.setLogicId(idWorker.nextId());

			obj.setReceiveNum(receiver);
			obj.setReceiveName("");

			obj.setMsg(message);
			obj.setSendTime(LocalDateTime.now());
			obj.setSendName(sender);
			obj.setUpdateTime(LocalDateTime.now());
			// 优先发送(1优先,0不优先
			obj.setPriority("0");
			// 是否需要回复(2.选人,1.需要,0.否)
			obj.setExt1(SMSToDoObj.STATUS_0);
			// 是否允许发送（默认0否，1是）
			obj.setExt3("1");
			// 租户逻辑ID
			obj.setExt5(organLogicId + "");
			Log.error("SMS：[ " + obj.getReceiveNum() + " ]  -> " + obj.getMsg() + " [ " + obj.getObjId() + " ]");
			smsToDoDao.save(obj);
		}
		return true;
	}
}
